package com.up.stores.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.up.stores.entity.Address;
import com.up.stores.entity.District;
import com.up.stores.mapper.AddressMapper;
import com.up.stores.mapper.DistrictMapper;
import com.up.stores.service.IAddressService;
import com.up.stores.service.IDistrictService;
import com.up.stores.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

//新增收货地址实现类
@Service
public class AddressServiceImpl implements IAddressService {
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private DistrictMapper districtMapper;
    @Autowired
    private IDistrictService districtService;

    @Value("${user.address.max-count}")
    private int maxCount;

    @Override
    public void addNewAddress(Integer uid, String type, String username, Address address) {
        // 根据参数uid调用addressMapper的countByUid(Integer uid)方法，统计当前用户的收货地址数据的数量
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        //此处判断当前用户类型
        if(type.equals("Admin")){
            queryWrapper.eq("adm_id", uid);
        }else{
            queryWrapper.eq("bus_id", uid);
        }

        Integer count = addressMapper.selectCount(queryWrapper);
        // 判断数量是否达到上限值
        if (count > maxCount) {
            // 是：抛出AddressCountLimitException
            throw new AddressCountLimitException("收货地址数量已经达到上限(" + maxCount + ")！");
        }
        // 补全数据：省、市、区的名称
        String provinceName = districtService.getNameByCode(address.getProvinceCode());
        String cityName = districtService.getNameByCode(address.getCityCode());
        if(address.getAreaCode() != null){String areaName = districtService.getNameByCode(address.getAreaCode()); address.setAreaName(areaName);}
        address.setProvinceName(provinceName);
        address.setCityName(cityName);

        // 补全数据：判断当前数据类型，将参数uid封装到参数address中
        if(type.equals("Admin")){
            address.setAdmId(uid);
        }else{
            address.setBusId(uid);
        }
        // 补全数据：根据以上统计的数量，得到正确的isDefault值(是否默认：0-不默认，1-默认)，并封装
        Integer isDefault = count == 0 ? 1 : 0;
        address.setIsDefault(isDefault);
        // 补全数据：4项日志
        Date now = new Date();
        address.setCreatedUser(username);
        address.setCreatedTime(now);
        address.setModifiedUser(username);
        address.setModifiedTime(now);
        System.out.println(address.toString());
        // 调用addressMapper的insert(Address address)方法插入收货地址数据，并获取返回的受影响行数
        Integer rows = addressMapper.insert(address);
        // 判断受影响行数是否不为1
        if (rows != 1) {
            // 是：抛出InsertException
            throw new InsertException("插入收货地址数据时出现未知错误，请联系系统管理员！");
        }
    }

    @Override
    public List<Address> getByUid(Integer uid, String type) {
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        if(type.equals("Admin")){
            queryWrapper.eq("adm_id", uid);
        }else{
            queryWrapper.eq("bus_id", uid);
        }
        List<Address> list = addressMapper.selectList(queryWrapper);
        //这里是为了减少数据的传输量
        /*for (Address address : list) {
            address.setProvinceCode(null);
            address.setCityCode(null);
            address.setAreaCode(null);
            address.setCreatedUser(null);
            address.setCreatedTime(null);
            address.setModifiedUser(null);
            address.setModifiedTime(null);
        }*/
        return list;
    }

    //修改地址
    @Override
    public void changeAddress(Integer addId, Integer uid, String type, String username, Address address) {
        // 查询收货地址数据
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("add_id", addId);
        Address result = addressMapper.selectOne(queryWrapper);
        // 判断查询结果是否为null
        if (result == null) {
            // 是：抛出AddressNotFoundException
            throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
        }
        //地址变化会发生编码变化，此处查找出该地址的对应编码
        //此处如果address中没有该省市县信息或信息出错（因为是选项框供选择所以一般不会）则会报错，是否需要在用户没有填满所有信息时报错？？？

        QueryWrapper<District> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("code", address.getProvinceCode());
        District district1 = districtMapper.selectOne(queryWrapper1);
        String ProvinceName = district1.getName();

        QueryWrapper<District> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("code", address.getCityCode());
        District district2 = districtMapper.selectOne(queryWrapper2);
        String CityName = district2.getName();

        //有些市没有区
        if(address.getAreaCode()!=null){
            QueryWrapper<District> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.eq("code", address.getAreaCode());
            District district3 = districtMapper.selectOne(queryWrapper3);
            String AreaName = district3.getName();
            address.setAreaName(AreaName);
        }

        //更新address其他表单外的内容:_code, modified_time, modified_user;
        address.setProvinceName(ProvinceName);
        address.setCityName(CityName);
        address.setModifiedTime(new Date());
        address.setModifiedUser(username);

        //根据add_id
        UpdateWrapper<Address> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("add_id", addId);
        addressMapper.update(address, updateWrapper);
    }

    @Transactional
    @Override
    public void setDefault(Integer addId, Integer uid, String type, String username) {
        // 查询收货地址数据
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("add_id", addId);

        Address result = addressMapper.selectOne(queryWrapper);
        // 判断查询结果是否为null
        if (result == null) {
            // 是：抛出AddressNotFoundException
            throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
        }
        // 判断查询结果中的uid与参数uid是否不一致(使用equals()判断)
//        if (!result.getAdmId().equals(uid)) {
//            // 是：抛出AccessDeniedExceptioneee
//            throw new AccessDeniedException("非法访问的异常");
//        }
        // 将该用户的所有收货地址全部设置为非默认，并获取返回受影响的行数
        UpdateWrapper<Address> updateWrapper = new UpdateWrapper<>();
        if(type.equals("Admin")){
            updateWrapper.eq("adm_id", uid).set("is_default", 0);
        }else{
            updateWrapper.eq("bus_id", uid).set("is_default", 0);
        }
        Integer rows = addressMapper.update(null, updateWrapper);
        // 判断受影响的行数是否小于1(不大于0)
        if (rows < 1) {
            // 是：抛出UpdateException
            throw new UpdateException("设置默认收货地址时出现未知错误[1]");
        }

        // 调用addressMapper的updateDefaultByAid()将指定aid的收货地址设置为默认，并获取返回的受影响的行数
        UpdateWrapper<Address> updateWrapper1 = new UpdateWrapper<>();
        updateWrapper1.eq("add_id", addId).set("is_default", 1);
        rows = addressMapper.update(null, updateWrapper1);
        // 判断受影响的行数是否不为1
        if (rows != 1) {
            // 是：抛出UpdateException
            throw new UpdateException("设置默认收货地址时出现未知错误[2]");
        }
    }
    //地址删除
    @Transactional
    @Override
    public void delete(Integer addId, Integer uid, String type, String username) {
        // 查询收货地址数据
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("add_id", addId);

        Address result = addressMapper.selectOne(queryWrapper);
        // 判断查询结果是否为null
        if (result == null) {
            // 是：抛出AddressNotFoundException
            throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
        }

//        // 判断查询结果中的uid与参数uid是否不一致(使用equals()判断)
//        if (!result.getAdmId().equals(uid)) {
//            // 是：抛出AccessDeniedException：非法访问
//            throw new AccessDeniedException("非常访问");
//        }

        // 根据参数aid，调用deleteByAid()执行删除
        Integer rows1 = addressMapper.delete(queryWrapper);
        if (rows1 != 1) {
            throw new DeleteException("删除收货地址数据时出现未知错误，请联系系统管理员");
        }

        // 判断查询结果中的isDefault是否为0
        if (result.getIsDefault() == 0) {
            return;
        }

        // 统计目前还有多少收货地址
        QueryWrapper<Address> queryWrapper1 = new QueryWrapper<>();
        //此处判断当前用户类型
        if(type.equals("Admin")){
            queryWrapper1.eq("adm_id", uid);
        }else{
            queryWrapper1.eq("bus_id", uid);
        }

        Integer count = addressMapper.selectCount(queryWrapper1);
        // 判断目前的收货地址的数量是否为0
        if (count == 0) {
            return;
        }

        // 调用findLastModified()找出用户最近修改的收货地址数据
        //这个findLastModified方法没有用Mybatis-plus写
        Address lastModified = new Address();
        if(type.equals("Admin")){
            lastModified = addressMapper.findLastModifiedByAdmId(uid);
        }else{
            lastModified = addressMapper.findLastModifiedByBusId(uid);
        }
        // 从以上查询结果中找出addId属性值
        Integer lastModifiedAddId = lastModified.getAddId();
        // 设置默认收货地址，并获取返回的受影响的行数
        UpdateWrapper<Address> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("add_id", lastModifiedAddId)
                     .set("is_default", 1)
                     .set("modified_user", username)
                     .set("modified_time", new Date());
        Integer rows2 = addressMapper.update(null, updateWrapper);
        // 判断受影响的行数是否不为1
        if (rows2 != 1) {
            // 是：抛出UpdateException
            throw new UpdateException("更新收货地址数据时出现未知错误，请联系系统管理员");
        }
    }

    @Override
    public Address getByAddIdAndType(Integer addId, Integer uid, String type){
        // 根据收货地址数据id，查询收货地址详情
        QueryWrapper<Address> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("add_id", addId);
        Address address = addressMapper.selectOne(queryWrapper);
        if (address == null) {
            throw new AddressNotFoundException("尝试访问的地址数据不存在");
        }
        if (!address.getAdmId().equals(uid)) {
            throw new AccessDeniedException("非法访问");
        }
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedUser(null);
        address.setCreatedTime(null);
        address.setModifiedUser(null);
        address.setModifiedTime(null);
        return address;
    }
}
